unit UtilsListView;

interface

uses
  Windows, Classes, CommCtrl;
  
  function GetListViewText(AListViewHandle: THandle; AListViewTexts: TStrings): Boolean;

implementation
                     
function ListViewColumnCount(AListViewHandle: THandle): Integer;
begin  
  Result := Header_GetItemCount(ListView_GetHeader(AListViewHandle));   
end;

function GetListViewText(AListViewHandle: THandle; AListViewTexts: TStrings): Boolean;   
var  
  vColumnCount: Integer;   
  vItemCount: Integer;   
  I, J: Integer;   
  vBuffer: array[0..255] of Char;   
  vProcessId: DWORD;   
  vProcess: THandle;   
  vPointer: Pointer;   
  vNumberOfBytesRead: Cardinal;   
  S: string;   
  vItem: TLVItem;   
begin  
  Result := False;
  if not IsWindow(AListViewHandle) then
    exit;
  if nil = AListViewTexts then
    Exit;
  vColumnCount := ListViewColumnCount(AListViewHandle);   
  if vColumnCount <= 0 then
    Exit;   
  vItemCount := ListView_GetItemCount(AListViewHandle);   
  GetWindowThreadProcessId(AListViewHandle, @vProcessId);   
  vProcess := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE, False, vProcessId);   
  vPointer := VirtualAllocEx(vProcess, nil, 4096, MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);   
  AListViewTexts.BeginUpdate;   
  try  
    AListViewTexts.Clear;   
    for I := 0 to vItemCount - 1 do
    begin
      S := '';
      for J := 0 to vColumnCount - 1 do
      begin
        vItem.mask := LVIF_TEXT;
        vItem.iItem := I;
        vItem.iSubItem := J;
        vItem.cchTextMax := SizeOf(vBuffer);
        vItem.pszText := Pointer(Cardinal(vPointer) + SizeOf(TLVItem));
   
        WriteProcessMemory(vProcess, vPointer, @vItem, SizeOf(TLVItem), vNumberOfBytesRead);   
        SendMessage(AListViewHandle, LVM_GETITEM, I, lparam(vPointer));   
        ReadProcessMemory(vProcess, Pointer(Cardinal(vPointer) + SizeOf(TLVItem)), @vBuffer[0], SizeOf(vBuffer), vNumberOfBytesRead);   
        S := S + #9 + vBuffer;   
      end;   
      Delete(S, 1, 1);   
      AListViewTexts.Add(S);   
    end;   
  finally  
    VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE);   
    CloseHandle(vProcess);   
    AListViewTexts.EndUpdate;
  end;   
  Result := True;   
end;

(*//
unit GetListViewDatas;
interface
uses
  Windows, Messages, SysUtils, CommCtrl, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
type
  TFormGetListViewDatas = class(TForm)
    mmoText: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    procedure WMHOTKEY(var Msg: TWMHOTKEY); message WM_HOTKEY;
    { Private declarations }
  public
    { Public declarations }
  end;
var
  FormGetListViewDatas: TFormGetListViewDatas;
implementation
{$R *.dfm}
function GetListViewSelectText(mHandle: THandle;var mStrings: string): Boolean;   
var  
  vColumnCount: Integer;
  I, J: Integer;
  vBuffer: array[0..255] of Char;   
  vProcessId: DWORD;   
  vProcess: THandle;   
  vPointer: Pointer;   
  vNumberOfBytesRead: Cardinal;   
  vItem: TLVItem;
begin  
  Result := False;   
  I := ListView_GetNextItem(mHandle, -1, LVNI_SELECTED);   
  if I = -1 then  
    Exit;  
  vColumnCount := ListViewColumnCount(mHandle);   
  if vColumnCount <= 0 then Exit;
  GetWindowThreadProcessId(mHandle, @vProcessId);
  vProcess := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or  
    PROCESS_VM_WRITE, False, vProcessId);   
  vPointer := VirtualAllocEx(vProcess, nil, 4096, MEM_RESERVE or MEM_COMMIT,   
    PAGE_READWRITE);  
  try
    mStrings := '';   
    for J := 0 to vColumnCount - 1 do  
    begin  
      with vItem do  
      begin  
        mask := LVIF_TEXT;   
        iItem := I;   
        iSubItem := J;   
        cchTextMax := SizeOf(vBuffer);   
        pszText := Pointer(Cardinal(vPointer) + SizeOf(TLVItem));   
      end;   
      WriteProcessMemory(vProcess, vPointer, @vItem,   
        SizeOf(TLVItem), vNumberOfBytesRead);   
      SendMessage(mHandle, LVM_GETITEM, I, lparam(vPointer));   
      ReadProcessMemory(vProcess, Pointer(Cardinal(vPointer) + SizeOf(TLVItem)),   
        @vBuffer[0], SizeOf(vBuffer), vNumberOfBytesRead);   
      mStrings := mStrings + #9 + vBuffer;   
    end;   
  finally  
    VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE);   
    CloseHandle(vProcess);
  end;   
  Result := True;   
end;
procedure TFormGetListViewDatas.FormCreate(Sender: TObject);
begin
  RegisterHotKey(Handle, 1, MOD_WIN, VK_F3);
end;
procedure TFormGetListViewDatas.WMHOTKEY(var Msg: TWMHOTKEY);
begin
  case Msg.HotKey of
    1:
      GetListViewText(
        WindowFromPoint(Point(Mouse.CursorPos.X, Mouse.CursorPos.Y)),
        mmoText.Lines);
  end;   
end;
procedure TFormGetListViewDatas.FormDestroy(Sender: TObject);
begin
  UnRegisterHotKey(Handle, 1);
end;
end.
//*)
end.
